/**
 * 为什么 Proxy 要配合 Reflect 一起使用？
 * 1.触发代理对象的劫持时保证正确的 this 上下文指向
 * 2.框架健壮性
 */
const person = {
  name: 'John',
  age: 30,
  get personalInfo() {
    return `${this.name} is ${this.age} years old.`;
  }
}

const p = new Proxy(person, {
  // receiver：修改属性访问中的 this 指向为传入的 receiver 对象
  get(target, key, receiver) {
    // 1.触发代理对象的劫持时保证正确的 this 上下文指向
    // console.log(receiver === p);
    // 可以简单的将 Reflect.get(target, key, receiver) 理解成为 target[key].call(receiver)，不过这是一段伪代码。
    return Reflect.get(target, key, receiver);
  }
})

console.log(p.name); // 输出 true

// JavaScript 是单线程语言，一旦抛出异常，后边的任何逻辑都不会执行，所以为了避免这种情况，我们在底层就要写 大量的 try catch 来避免，不够优雅。
// Object.defineProperty(p, 'height', {
//   get() {
//     return 180
//   }
// })
// 此时的日志是打不出来的，因为使用 Object.defineProperty() 重复声明的属性 报错了，
// console.log('lalalalala');

const h1 = Reflect.defineProperty(person, 'height', {
  get() {
    return 180
  }
})

const h2 = Reflect.defineProperty(person, 'height', {
  get() {
    return 175
  }
})
// 我们可以看到使用 Reflect.defineProperty() 是有返回值的，所以通过 返回值 来判断你当前操作是否成功。
console.log(h1);
console.log(h2);
console.log(p);
